package org.ccay.sitemap.service.impl.internal;

import java.util.Collection;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.ccay.core.util.CollectionUtil;
import org.ccay.sitemap.SiteNodeVO;

/**
 * 用于菜单权限判断的安全工具
 * 
 * @author chaowangbang
 * @since 2011-11-22
 */
public final class SiteMapSecurityUtil {
	/**
	 * 防止创建实例
	 */
	private SiteMapSecurityUtil(){
	}

	/**
	 * 判断可见
	 * 
	 * @param node
	 * @param children
	 * @param grantedOperations
	 * @return
	 */
	public static boolean checkVisible(SiteNodeVO node,
			List<SiteNodeVO> children, Collection<String> grantedOperations) {
		String control = node.getControl();
		if(SiteNodeVO.VISIBLE_PUBLIC.equals(control)){
			return true;
		}else if (SiteNodeVO.VISIBLE_TO_EVERYONE.equals(control)) {
			return SecurityUtils.getSubject().isAuthenticated();
		} else if (SiteNodeVO.VISIBLE_TO_FUNCTION.equals(control)) {
			return checkNodePermission(node.getPermissionString(), grantedOperations);
		} else if (SiteNodeVO.VISIBLE_BY_CHILDREN.equals(control)) {
			return checkPermission(children, grantedOperations);
		}

		return false;
	}

	/**
	 * 根据绑定的功能点判断权限
	 * 
	 * @param accessName
	 * @param grantedOperations
	 * @return
	 */
	private static boolean checkNodePermission(String accessName,
			Collection<String> grantedOperations) {
		return grantedOperations.contains(accessName);
	}

	/**
	 * 根据Children的可见性判断权限
	 * 
	 * @param children
	 * @param grantedOperations
	 * @return
	 */
	private static boolean checkPermission(List<SiteNodeVO> children,
			Collection<String> grantedOperations) {
		if ( CollectionUtil.isNullOrEmpty(children) ) {
			return false;
		}

		for (SiteNodeVO child : children) {
			if (isChildVisible(grantedOperations, child)) {
				return true;
			}
		}
		return false;
	}

	/** 
	 * 节点是否可见
	 * @param grantedOperations
	 * @param child
	 * @return
	 */
	private static boolean isChildVisible(Collection<String> grantedOperations,
			SiteNodeVO child) {
		return child.isVisible()
				&& checkVisible(child, child.getChildren(),
						grantedOperations);
	}
}
